package com.toolsder.demo.spring.security.jwt.config;

import com.google.common.base.Strings;
import com.toolsder.demo.spring.security.jwt.annotation.RoleMsg;
import com.toolsder.demo.spring.security.jwt.annotation.SystemRole;
import com.toolsder.demo.spring.security.jwt.entity.database.Resources;
import com.toolsder.demo.spring.security.jwt.service.ResourcesService;
import com.toolsder.demo.spring.security.jwt.service.RoleService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * created by 猴子请来的逗比 On 2020/9/11
 *
 * @author by 猴子请来的逗比
 */
@Component
public class InitRoleAndResources {
    /**
     * spring  上下文
     */
    @Resource
    private ApplicationContext applicationContext;

    /**
     * 资源
     */
    @Resource
    private ResourcesService resourcesService;

    /**
     * 角色
     */
    @Resource
    private RoleService roleService;

    /**
     * 当注入完成后执行该方法
     */
    @PostConstruct
    public void init() {
        this.initResources();
        this.initAdminRole();
    }

    /**
     * 初始化资源，依据系统中的注解信息
     */
    private void initResources() {
        RequestMappingHandlerMapping bean = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = bean.getHandlerMethods();
        for (RequestMappingInfo rmi : handlerMethods.keySet()) {
            //获取资源路径名称
            String name = rmi.getName();
            //判断资源路径的name是否存在
            if (!Strings.isNullOrEmpty(name)) {
                //获取资源路径
                List<Resources> resourcesList = new ArrayList<>();
                Set<String> patterns = rmi.getPatternsCondition().getPatterns();
                for (String pattern : patterns) {
                    Resources resources;
                    if (!resourcesService.existsByResourcesUrl(pattern)) {
                        //保存资源
                        resources = resourcesService.save(pattern, name);
                    } else {
                        resources = resourcesService.updateName(pattern, name);
                    }
                    resourcesList.add(resources);
                }
                //获取资源路径的方法
                HandlerMethod handlerMethod = handlerMethods.get(rmi);
                //获取方法上的权限注解
                SystemRole annotation = handlerMethod.getMethod().getAnnotation(SystemRole.class);
                RoleMsg[] roleMsgs = annotation.roleMsg();
                for (RoleMsg roleMsg : roleMsgs) {
                    if (!roleService.existsByRoleCode(roleMsg.code())) {
                        roleService.create(roleMsg.code(), roleMsg.name(), roleMsg.descpt());
                    } else {
                        roleService.updateMessage(roleMsg.code(), roleMsg.name(), roleMsg.descpt());
                    }
                    //为权限配置资源路径
                    roleService.updateResources(roleMsg.code(), resourcesList);
                }

            }
        }
    }


    /**
     * 初始化超级管理员
     */
    private void initAdminRole() {
        List<Resources> resources = resourcesService.findAll();
        String ROLE_NAME = "SUPER_ADMIN";
        if (!roleService.existsByRoleCode(ROLE_NAME)) {
            roleService.createSuperAdmin(ROLE_NAME, "超级管理员", "超级管理员", resources);
        } else {
            roleService.updateSuperAdminResources(ROLE_NAME, resources);
        }
    }
}
